#include "StdAfx.h"
#include "SampleGrabberCB.h"
#include <qedit.h>


// Structures
CALLBACKINFO cbInfo={0};

CSampleGrabberCB::CSampleGrabberCB(void)
{
 	m_hOwner = NULL;
	m_bOneShot = FALSE;
	m_lWidth = 0;
	m_lHeight = 0;
	ZeroMemory(m_szCapDir, sizeof(m_szCapDir));
	ZeroMemory(m_szSnappedName, sizeof(m_szSnappedName));
}

CSampleGrabberCB::~CSampleGrabberCB(void)
{
}

STDMETHODIMP CSampleGrabberCB::QueryInterface(REFIID riid, void ** ppv)
{
	if( riid == IID_ISampleGrabberCB || riid == IID_IUnknown ) 
	{
		*ppv = (void *) static_cast<ISampleGrabberCB*> ( this );
		return NOERROR;
	}    
	return E_NOINTERFACE;
}

void CSampleGrabberCB::SetFilePath(const char* pPath)
{
	ASSERT(pPath);
	ASSERT(strlen(pPath) < MAX_PATH);

	strcpy(m_szCapDir,pPath);
}

BOOL CSampleGrabberCB::SaveBitmap( double dblSampleTime, BYTE * pBuffer, long lBufferSize )
{
	if( !m_bOneShot || !pBuffer )
		return 0;

	// we only take one at a time
	//
	m_bOneShot = FALSE;

	// figure out where to capture to
	//
// 	TCHAR m_ShortName[MAX_PATH];
	static int nCapNum = 0;

	wsprintf( m_szSnappedName, TEXT("%sStillCap%4.4ld.bmp\0"), 
		m_szCapDir, nCapNum++ );
// 
// 	wsprintf( m_ShortName, TEXT("StillCap%4.4ld.bmp\0"), 
// 		pOwner->m_nCapTimes );
// 
// 	// increment bitmap number if user requested it
// 	// otherwise, we'll reuse the filename next time
// 	if( pOwner->IsDlgButtonChecked( IDC_AUTOBUMP ) )
// 		pOwner->m_nCapTimes++;

	// write out a BMP file
	//
	HANDLE hf = CreateFile(
		m_szSnappedName, GENERIC_WRITE, FILE_SHARE_READ, NULL,
		CREATE_ALWAYS, NULL, NULL );

	if( hf == INVALID_HANDLE_VALUE )
		return 0;

	// write out the file header
	//
	BITMAPFILEHEADER bfh;
	memset( &bfh, 0, sizeof( bfh ) );
	bfh.bfType = 'MB';
	bfh.bfSize = sizeof( bfh ) + lBufferSize + sizeof( BITMAPINFOHEADER );
	bfh.bfOffBits = sizeof( BITMAPINFOHEADER ) + sizeof( BITMAPFILEHEADER );

	DWORD dwWritten = 0;
	WriteFile( hf, &bfh, sizeof( bfh ), &dwWritten, NULL );

	// and the bitmap format
	//
	BITMAPINFOHEADER bih;
	memset( &bih, 0, sizeof( bih ) );
	bih.biSize = sizeof( bih );
	bih.biWidth = m_lWidth;
	bih.biHeight = m_lHeight;
	bih.biPlanes = 1;
	bih.biBitCount = 24;

	dwWritten = 0;
	WriteFile( hf, &bih, sizeof( bih ), &dwWritten, NULL );

	// and the bits themselves
	//
	dwWritten = 0;
	WriteFile( hf, pBuffer, lBufferSize, &dwWritten, NULL );
	CloseHandle( hf );

	// Save bitmap header for later use when repainting the window
	memcpy(&(cbInfo.bih), &bih, sizeof(bih));

	return 0;
}

STDMETHODIMP CSampleGrabberCB::BufferCB( double dblSampleTime, BYTE * pBuffer, long lBufferSize )
{
	// this flag will get set to true in order to take a picture
	//
	if( !m_bOneShot )
		return 0;

	if (!pBuffer)
		return E_POINTER;

	if( cbInfo.lBufferSize < lBufferSize )
	{
		delete [] cbInfo.pBuffer;
		cbInfo.pBuffer = NULL;
		cbInfo.lBufferSize = 0;
	}

	// Since we can't access Windows API functions in this callback, just
	// copy the bitmap data to a global structure for later reference.
	cbInfo.dblSampleTime = dblSampleTime;

	// If we haven't yet allocated the data buffer, do it now.
	// Just allocate what we need to store the new bitmap.
	if (!cbInfo.pBuffer)
	{
		cbInfo.pBuffer = new BYTE[lBufferSize];
		cbInfo.lBufferSize = lBufferSize;
	}

	if( !cbInfo.pBuffer )
	{
		cbInfo.lBufferSize = 0;
		return E_OUTOFMEMORY;
	}

	// Copy the bitmap data into our global buffer
	memcpy(cbInfo.pBuffer, pBuffer, lBufferSize);

	// Post a message to our application, telling it to come back
	// and write the saved data to a bitmap file on the user's disk.
	PostMessage(m_hOwner, WM_CAPTURE_BITMAP, 0, 0L);
	return 0;
}